﻿using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework;
using Terraria.DataStructures;
using Terraria.ID;

namespace Terraria.GameContent.Tile_Entities
{
	// Token: 0x0200040C RID: 1036
	public class TELogicSensor : TileEntity
	{
		// Token: 0x0600243C RID: 9276 RVA: 0x00019A3A File Offset: 0x00017C3A
		public static void Initialize()
		{
			TileEntity._UpdateStart += TELogicSensor.UpdateStartInternal;
			TileEntity._UpdateEnd += TELogicSensor.UpdateEndInternal;
			TileEntity._NetPlaceEntity += TELogicSensor.NetPlaceEntity;
		}

		// Token: 0x0600243D RID: 9277 RVA: 0x0047C918 File Offset: 0x0047AB18
		public static void NetPlaceEntity(int x, int y, int type)
		{
			if (type != 2)
			{
				return;
			}
			if (!TELogicSensor.ValidTile(x, y))
			{
				return;
			}
			int num = TELogicSensor.Place(x, y);
			((TELogicSensor)TileEntity.ByID[num]).FigureCheckState();
			NetMessage.SendData(86, -1, -1, null, num, (float)x, (float)y, 0f, 0, 0, 0);
		}

		// Token: 0x0600243E RID: 9278 RVA: 0x00019A6F File Offset: 0x00017C6F
		private static void UpdateStartInternal()
		{
			TELogicSensor.inUpdateLoop = true;
			TELogicSensor.markedIDsForRemoval.Clear();
			TELogicSensor.playerBox.Clear();
			TELogicSensor.playerBoxFilled = false;
			TELogicSensor.FillPlayerHitboxes();
		}

		// Token: 0x0600243F RID: 9279 RVA: 0x0047C968 File Offset: 0x0047AB68
		private static void FillPlayerHitboxes()
		{
			if (!TELogicSensor.playerBoxFilled)
			{
				for (int i = 0; i < 255; i++)
				{
					if (Main.player[i].active)
					{
						TELogicSensor.playerBox[i] = Main.player[i].getRect();
					}
				}
				TELogicSensor.playerBoxFilled = true;
			}
		}

		// Token: 0x06002440 RID: 9280 RVA: 0x0047C9B8 File Offset: 0x0047ABB8
		private static void UpdateEndInternal()
		{
			TELogicSensor.inUpdateLoop = false;
			foreach (Tuple<Point16, bool> tuple in TELogicSensor.tripPoints)
			{
				Wiring.blockPlayerTeleportationForOneIteration = tuple.Item2;
				Wiring.HitSwitch((int)tuple.Item1.X, (int)tuple.Item1.Y);
			}
			Wiring.blockPlayerTeleportationForOneIteration = false;
			TELogicSensor.tripPoints.Clear();
			foreach (int key in TELogicSensor.markedIDsForRemoval)
			{
				TileEntity tileEntity;
				if (TileEntity.ByID.TryGetValue(key, out tileEntity) && tileEntity.type == 2)
				{
					TileEntity.ByID.Remove(key);
				}
				TileEntity.ByPosition.Remove(tileEntity.Position);
			}
			TELogicSensor.markedIDsForRemoval.Clear();
		}

		// Token: 0x06002441 RID: 9281 RVA: 0x0047CABC File Offset: 0x0047ACBC
		public override void Update()
		{
			bool state = TELogicSensor.GetState((int)this.Position.X, (int)this.Position.Y, this.logicCheck, this);
			TELogicSensor.LogicCheckType logicCheckType = this.logicCheck;
			if (logicCheckType - TELogicSensor.LogicCheckType.Day > 1)
			{
				if (logicCheckType - TELogicSensor.LogicCheckType.PlayerAbove > 4)
				{
					return;
				}
				if (this.On != state)
				{
					this.ChangeState(state, true);
					return;
				}
			}
			else
			{
				if (!this.On && state)
				{
					this.ChangeState(true, true);
				}
				if (this.On && !state)
				{
					this.ChangeState(false, false);
					return;
				}
			}
		}

		// Token: 0x06002442 RID: 9282 RVA: 0x0047CB3C File Offset: 0x0047AD3C
		public void ChangeState(bool onState, bool TripWire)
		{
			if (onState != this.On && !TELogicSensor.SanityCheck((int)this.Position.X, (int)this.Position.Y))
			{
				return;
			}
			Main.tile[(int)this.Position.X, (int)this.Position.Y].frameX = (onState ? 18 : 0);
			this.On = onState;
			if (Main.netMode == 2)
			{
				NetMessage.SendTileSquare(-1, (int)this.Position.X, (int)this.Position.Y, 1, TileChangeType.None);
			}
			if (TripWire && Main.netMode != 1)
			{
				TELogicSensor.tripPoints.Add(Tuple.Create<Point16, bool>(this.Position, this.logicCheck == TELogicSensor.LogicCheckType.PlayerAbove));
			}
		}

		// Token: 0x06002443 RID: 9283 RVA: 0x0047CBF4 File Offset: 0x0047ADF4
		public static bool ValidTile(int x, int y)
		{
			return Main.tile[x, y].active() && Main.tile[x, y].type == 423 && Main.tile[x, y].frameY % 18 == 0 && Main.tile[x, y].frameX % 18 == 0;
		}

		// Token: 0x06002444 RID: 9284 RVA: 0x00019A96 File Offset: 0x00017C96
		public TELogicSensor()
		{
			this.logicCheck = TELogicSensor.LogicCheckType.None;
			this.On = false;
		}

		// Token: 0x06002445 RID: 9285 RVA: 0x0047CC5C File Offset: 0x0047AE5C
		public static TELogicSensor.LogicCheckType FigureCheckType(int x, int y, out bool on)
		{
			on = false;
			if (!WorldGen.InWorld(x, y, 0))
			{
				return TELogicSensor.LogicCheckType.None;
			}
			Tile tile = Main.tile[x, y];
			if (tile == null)
			{
				return TELogicSensor.LogicCheckType.None;
			}
			TELogicSensor.LogicCheckType logicCheckType = TELogicSensor.LogicCheckType.None;
			switch (tile.frameY / 18)
			{
			case 0:
				logicCheckType = TELogicSensor.LogicCheckType.Day;
				break;
			case 1:
				logicCheckType = TELogicSensor.LogicCheckType.Night;
				break;
			case 2:
				logicCheckType = TELogicSensor.LogicCheckType.PlayerAbove;
				break;
			case 3:
				logicCheckType = TELogicSensor.LogicCheckType.Water;
				break;
			case 4:
				logicCheckType = TELogicSensor.LogicCheckType.Lava;
				break;
			case 5:
				logicCheckType = TELogicSensor.LogicCheckType.Honey;
				break;
			case 6:
				logicCheckType = TELogicSensor.LogicCheckType.Liquid;
				break;
			}
			on = TELogicSensor.GetState(x, y, logicCheckType, null);
			return logicCheckType;
		}

		// Token: 0x06002446 RID: 9286 RVA: 0x0047CCE0 File Offset: 0x0047AEE0
		public static bool GetState(int x, int y, TELogicSensor.LogicCheckType type, TELogicSensor instance = null)
		{
			switch (type)
			{
			case TELogicSensor.LogicCheckType.Day:
				return Main.dayTime;
			case TELogicSensor.LogicCheckType.Night:
				return !Main.dayTime;
			case TELogicSensor.LogicCheckType.PlayerAbove:
			{
				bool result = false;
				Rectangle value = new Rectangle(x * 16 - 32 - 1, y * 16 - 160 - 1, 82, 162);
				foreach (KeyValuePair<int, Rectangle> keyValuePair in TELogicSensor.playerBox)
				{
					if (keyValuePair.Value.Intersects(value))
					{
						result = true;
						break;
					}
				}
				return result;
			}
			case TELogicSensor.LogicCheckType.Water:
			case TELogicSensor.LogicCheckType.Lava:
			case TELogicSensor.LogicCheckType.Honey:
			case TELogicSensor.LogicCheckType.Liquid:
			{
				if (instance == null)
				{
					return false;
				}
				Tile tile = Main.tile[x, y];
				bool flag = true;
				if (tile == null || tile.liquid == 0)
				{
					flag = false;
				}
				if (!tile.lava() && type == TELogicSensor.LogicCheckType.Lava)
				{
					flag = false;
				}
				if (!tile.honey() && type == TELogicSensor.LogicCheckType.Honey)
				{
					flag = false;
				}
				if ((tile.honey() || tile.lava()) && type == TELogicSensor.LogicCheckType.Water)
				{
					flag = false;
				}
				if (!flag && instance.On)
				{
					if (instance.CountedData == 0)
					{
						instance.CountedData = 15;
					}
					else if (instance.CountedData > 0)
					{
						instance.CountedData--;
					}
					flag = (instance.CountedData > 0);
				}
				return flag;
			}
			default:
				return false;
			}
		}

		// Token: 0x06002447 RID: 9287 RVA: 0x0047CE44 File Offset: 0x0047B044
		public void FigureCheckState()
		{
			this.logicCheck = TELogicSensor.FigureCheckType((int)this.Position.X, (int)this.Position.Y, out this.On);
			TELogicSensor.GetFrame((int)this.Position.X, (int)this.Position.Y, this.logicCheck, this.On);
		}

		// Token: 0x06002448 RID: 9288 RVA: 0x0047CEA0 File Offset: 0x0047B0A0
		public static void GetFrame(int x, int y, TELogicSensor.LogicCheckType type, bool on)
		{
			Main.tile[x, y].frameX = (on ? 18 : 0);
			switch (type)
			{
			case TELogicSensor.LogicCheckType.Day:
				Main.tile[x, y].frameY = 0;
				return;
			case TELogicSensor.LogicCheckType.Night:
				Main.tile[x, y].frameY = 18;
				return;
			case TELogicSensor.LogicCheckType.PlayerAbove:
				Main.tile[x, y].frameY = 36;
				return;
			case TELogicSensor.LogicCheckType.Water:
				Main.tile[x, y].frameY = 54;
				return;
			case TELogicSensor.LogicCheckType.Lava:
				Main.tile[x, y].frameY = 72;
				return;
			case TELogicSensor.LogicCheckType.Honey:
				Main.tile[x, y].frameY = 90;
				return;
			case TELogicSensor.LogicCheckType.Liquid:
				Main.tile[x, y].frameY = 108;
				return;
			default:
				Main.tile[x, y].frameY = 0;
				return;
			}
		}

		// Token: 0x06002449 RID: 9289 RVA: 0x00019AAC File Offset: 0x00017CAC
		public static bool SanityCheck(int x, int y)
		{
			if (!Main.tile[x, y].active() || Main.tile[x, y].type != 423)
			{
				TELogicSensor.Kill(x, y);
				return false;
			}
			return true;
		}

		// Token: 0x0600244A RID: 9290 RVA: 0x0047CF8C File Offset: 0x0047B18C
		public static int Place(int x, int y)
		{
			TELogicSensor telogicSensor = new TELogicSensor();
			telogicSensor.Position = new Point16(x, y);
			telogicSensor.ID = TileEntity.AssignNewID();
			telogicSensor.type = 2;
			TileEntity.ByID[telogicSensor.ID] = telogicSensor;
			TileEntity.ByPosition[telogicSensor.Position] = telogicSensor;
			return telogicSensor.ID;
		}

		// Token: 0x0600244B RID: 9291 RVA: 0x0047CFE8 File Offset: 0x0047B1E8
		public static int Hook_AfterPlacement(int x, int y, int type = 423, int style = 0, int direction = 1)
		{
			bool on;
			TELogicSensor.LogicCheckType type2 = TELogicSensor.FigureCheckType(x, y, out on);
			TELogicSensor.GetFrame(x, y, type2, on);
			if (Main.netMode == 1)
			{
				NetMessage.SendTileSquare(Main.myPlayer, x, y, 1, TileChangeType.None);
				NetMessage.SendData(87, -1, -1, null, x, (float)y, 2f, 0f, 0, 0, 0);
				return -1;
			}
			int num = TELogicSensor.Place(x, y);
			((TELogicSensor)TileEntity.ByID[num]).FigureCheckState();
			return num;
		}

		// Token: 0x0600244C RID: 9292 RVA: 0x0047D058 File Offset: 0x0047B258
		public static void Kill(int x, int y)
		{
			TileEntity tileEntity;
			if (TileEntity.ByPosition.TryGetValue(new Point16(x, y), out tileEntity) && tileEntity.type == 2)
			{
				Wiring.blockPlayerTeleportationForOneIteration = (((TELogicSensor)tileEntity).logicCheck == TELogicSensor.LogicCheckType.PlayerAbove);
				if (((TELogicSensor)tileEntity).logicCheck == TELogicSensor.LogicCheckType.PlayerAbove && ((TELogicSensor)tileEntity).On)
				{
					Wiring.HitSwitch((int)tileEntity.Position.X, (int)tileEntity.Position.Y);
				}
				if (((TELogicSensor)tileEntity).logicCheck == TELogicSensor.LogicCheckType.Water && ((TELogicSensor)tileEntity).On)
				{
					Wiring.HitSwitch((int)tileEntity.Position.X, (int)tileEntity.Position.Y);
				}
				if (((TELogicSensor)tileEntity).logicCheck == TELogicSensor.LogicCheckType.Lava && ((TELogicSensor)tileEntity).On)
				{
					Wiring.HitSwitch((int)tileEntity.Position.X, (int)tileEntity.Position.Y);
				}
				if (((TELogicSensor)tileEntity).logicCheck == TELogicSensor.LogicCheckType.Honey && ((TELogicSensor)tileEntity).On)
				{
					Wiring.HitSwitch((int)tileEntity.Position.X, (int)tileEntity.Position.Y);
				}
				if (((TELogicSensor)tileEntity).logicCheck == TELogicSensor.LogicCheckType.Liquid && ((TELogicSensor)tileEntity).On)
				{
					Wiring.HitSwitch((int)tileEntity.Position.X, (int)tileEntity.Position.Y);
				}
				Wiring.blockPlayerTeleportationForOneIteration = false;
				if (TELogicSensor.inUpdateLoop)
				{
					TELogicSensor.markedIDsForRemoval.Add(tileEntity.ID);
					return;
				}
				TileEntity.ByPosition.Remove(new Point16(x, y));
				TileEntity.ByID.Remove(tileEntity.ID);
			}
		}

		// Token: 0x0600244D RID: 9293 RVA: 0x0047D1EC File Offset: 0x0047B3EC
		public static int Find(int x, int y)
		{
			TileEntity tileEntity;
			if (TileEntity.ByPosition.TryGetValue(new Point16(x, y), out tileEntity) && tileEntity.type == 2)
			{
				return tileEntity.ID;
			}
			return -1;
		}

		// Token: 0x0600244E RID: 9294 RVA: 0x00019AE3 File Offset: 0x00017CE3
		public override void WriteExtraData(BinaryWriter writer, bool networkSend)
		{
			if (!networkSend)
			{
				writer.Write((byte)this.logicCheck);
				writer.Write(this.On);
			}
		}

		// Token: 0x0600244F RID: 9295 RVA: 0x00019B01 File Offset: 0x00017D01
		public override void ReadExtraData(BinaryReader reader, bool networkSend)
		{
			if (!networkSend)
			{
				this.logicCheck = (TELogicSensor.LogicCheckType)reader.ReadByte();
				this.On = reader.ReadBoolean();
			}
		}

		// Token: 0x06002450 RID: 9296 RVA: 0x0047D220 File Offset: 0x0047B420
		public override string ToString()
		{
			return string.Concat(new object[]
			{
				this.Position.X,
				"x  ",
				this.Position.Y,
				"y ",
				this.logicCheck
			});
		}

		// Token: 0x04004029 RID: 16425
		private static Dictionary<int, Rectangle> playerBox = new Dictionary<int, Rectangle>();

		// Token: 0x0400402A RID: 16426
		private static List<Tuple<Point16, bool>> tripPoints = new List<Tuple<Point16, bool>>();

		// Token: 0x0400402B RID: 16427
		private static List<int> markedIDsForRemoval = new List<int>();

		// Token: 0x0400402C RID: 16428
		private static bool inUpdateLoop = false;

		// Token: 0x0400402D RID: 16429
		private static bool playerBoxFilled = false;

		// Token: 0x0400402E RID: 16430
		public TELogicSensor.LogicCheckType logicCheck;

		// Token: 0x0400402F RID: 16431
		public bool On;

		// Token: 0x04004030 RID: 16432
		public int CountedData;

		// Token: 0x0200040D RID: 1037
		public enum LogicCheckType
		{
			// Token: 0x04004032 RID: 16434
			None,
			// Token: 0x04004033 RID: 16435
			Day,
			// Token: 0x04004034 RID: 16436
			Night,
			// Token: 0x04004035 RID: 16437
			PlayerAbove,
			// Token: 0x04004036 RID: 16438
			Water,
			// Token: 0x04004037 RID: 16439
			Lava,
			// Token: 0x04004038 RID: 16440
			Honey,
			// Token: 0x04004039 RID: 16441
			Liquid
		}
	}
}
